/* ***** BEGIN LICENSE BLOCK *****
 *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is ThumbsDown.
 *
 * The Initial Developer of the Original Code is
 * Atte Kemppilä.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 * ***** END LICENSE BLOCK ***** */


function ThumbnailsPage() // extend WizardPage
{
    var depends = "thumbnails";
    WizardPage.call(this, depends);
    
    this.selected = [];
    this.thumbnailIndex = null;
}

ThumbnailsPage.prototype =
{
    get filterThumbnails() { return $("cbox_filterThumbnails") },
    
    get tree() { return $("tree_thumbnails"); },
    
    get filter()
    {
        if (! this.filterThumbnails.checked)
            return null;
        
        var minWidth = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailWidth");
        var minHeight = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailHeight");
        var mode = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailMode");
        var boundingBox = new Box(minWidth, minHeight);
        
        return function(thumbnail)
        {
            var image = thumbnail.thumbnailImage;
            if (! image)
                return false;
            
            var imageBox = new Box(image.width, image.height);
            return boundingBox.contains(imageBox, (mode == FILTER_MODE_EITHER));
        };
    },
    
    onPageShow: function()
    {
        if (this.firstRun)
        {
            var self = this;
            $("treechildren_thumbnails").addEventListener("DOMMouseScroll", function(e) { self.onThumbnailTreeMouseMove(e); }, false);
            $("image_thumbnail").addEventListener("load", function() { self.onThumbnailLoad(); }, false);
            
            wizard.addPrefObserver(this, "extensions.thumbsdown.scriptwizard.", false);
        }
        
        if (this.dirty.thumbnails)
            this.tree.view = this.treeView = new ThumbnailsTreeView(model.thumbnails, this.filter);
        
        if (this.dirty.page)
            this._updateSelected();
        
        this._updateThumbnailSize();
    },
    
    observe: function(subject, topic, data)
    {
        var prefNamePrefix = "extensions.thumbsdown.scriptwizard.";
        
        switch (data.substr(prefNamePrefix.length))
        {
            case "minThumbnailWidth":
            case "minThumbnailHeight":
            case "minThumbnailMode":
                callLater(0, this, this._updateFilter);
                break;
        }
    },
    
    onThumbnailTreeSelect: function()
    {
        this._updateSelected();
        wizard.updateWizardButtons();
    },
    
    onThumbnailTreeKeyUp: function()
    {
        this._setThumbnail(this.tree.currentIndex);
    },
    
    onThumbnailTreeMouseMove: function(e)
    {
        let row = {}, col = {};
        this.tree.treeBoxObject.getCellAt(e.clientX, e.clientY, row, col, {});
        [row, col] = [row.value, col.value];
        
        this._setThumbnail((row >= 0) ? this.treeView.model[row].index : null);
        
        if (row >= 0)
            this._updateTreeTooltip(this.treeView.getTooltipText(row, col));
    },
    
    onThumbnailTreeMouseOut: function(e)
    {
        // TODO: don't remove thumbnail when over context menu
        this._setThumbnail(null);
    },
    
    onThumbnailTreeContextMenuShowing: function(e)
    {
        var row = this.tree.treeBoxObject.getRowAt(e.clientX, e.clientY);
        if (row == -1)
        {
            e.preventDefault();
            return;
        }
        
        $("mitem_showLargerThumbnail").disabled = this.filterThumbnails.checked;
    },
    
    onThumbnailLoad: function()
    {
        if (page != pages.thumbnails)
            return;
        
        this._updateThumbnailSize();
    },
    
    onFilterThumbnailsChange: function()
    {
        this._updateFilter();
    },
    
    onHideSmaller: function()
    {
        var row = this.tree.currentIndex;
        var thumbnail = this.treeView.model[row];
        var image = thumbnail.thumbnailImage;
        
        var minWidth = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailWidth");
        var minHeight = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailHeight");
        var mode = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailMode");
        
        var minBox = new Box(minWidth, minHeight);
        var imageBox = new Box(image.width, image.height);
        minBox.enlarge(imageBox, (mode == FILTER_MODE_EITHER));
        
        ThumbsDown.prefs.setIntPref("scriptwizard.minThumbnailWidth", minBox.width);
        ThumbsDown.prefs.setIntPref("scriptwizard.minThumbnailHeight", minBox.height);
        
        this.filterThumbnails.checked = true;
        this._updateFilter();
    },
    
    onShowLarger: function()
    {
        var row = this.tree.currentIndex;
        var thumbnail = this.treeView.model[row];
        var image = thumbnail.thumbnailImage;
        
        var minWidth = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailWidth");
        var minHeight = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailHeight");
        var mode = ThumbsDown.prefs.getIntPref("scriptwizard.minThumbnailMode");
        
        var minBox = new Box(minWidth, minHeight);
        var imageBox = new Box(Math.max(0, image.width - 1), Math.max(0, image.height - 1));
        minBox.shrink(imageBox, (mode == FILTER_MODE_BOTH));
        
        ThumbsDown.prefs.setIntPref("scriptwizard.minThumbnailWidth", minBox.width);
        ThumbsDown.prefs.setIntPref("scriptwizard.minThumbnailHeight", minBox.height);
        
        this.filterThumbnails.checked = true;
        this._updateFilter();
    },
    
    canAdvance: function()
    {
        // at least 2 thumbnails must be selected
        if (this.selected.length < 2)
            return false;
        
        // all selected thumbnails' type must be the same
        let type = this.selected[0].type;
        for each (let thumbnail in this.selected)
            if (thumbnail.type != type)
                return false;
        
        return true;
    },
    
    _setThumbnail: function(index)
    {
        if (index == this.thumbnailIndex)
            return;
        
        this.thumbnailIndex = index;
        
        var image = $("image_thumbnail");
        if (index != null)
        {
            var thumbnail = model.thumbnails[index];
            
            var boxComputedStyle = document.defaultView.getComputedStyle($("box_thumbnail"), null);
            var boxWidth = boxComputedStyle.width.replace(/px$/, "");
            var boxHeight = boxComputedStyle.height.replace(/px$/, "");
            
            image.src = thumbnail.thumbnailUrl;
            image.setSize(boxWidth, boxHeight);
        }
        else
        {
            image.src = "";
            this._updateThumbnailSize();
        }
    },
    
    _updateTreeTooltip: function(text)
    {
        $("treechildren_thumbnails").setAttribute("tooltiptext", text);
    },
    
    _updateSelected: function()
    {
        this.selected = [this.treeView.model[row] for each (row in SelectionIterator(this.tree.view.selection))];
        
        var selectedCount = this.selected.length;
        var rowCount = this.treeView.rowCount;
        var thumbnailCount = this.treeView.originalCount;
        
        var msg = selectedCount + " / " + rowCount;
        if (rowCount != thumbnailCount)
            msg += " (" + thumbnailCount + ")"
        
        $("lbl_thumbnails_count").value = msg;
    },
    
    _updateThumbnailSize: function()
    {
        var index = this.thumbnailIndex;
        var show = (index != null);
        if (show)
        {
            var image = model.thumbnails[index].thumbnailImage;
            if (image)
                $("lbl_thumbnailSize").value = image.width + "x" + image.height;
        }
        $("lbl_thumbnailSize").parentNode.style.visibility = ((show && image) ? "visible" : "hidden");
    },
    
    _updateFilter: function()
    {
        this.treeView.filter = this.filter;
        
        if (page != pages.thumbnails)
        {
            this.dirty.page = true;
            return;
        }
        
        this._updateSelected();
    },
    
    onPageAdvanced: function()
    {
        model.selected = this.selected;
        model.matchingScript = scriptWizard.getMatchingScript(model.selected);
        model.thumbnailType = this.selected[0].type;
        
        if (model.matchingScript)
            return wizard.advance("script");
        
        return true;
    }
}

extend(ThumbnailsPage, WizardPage);

pages.thumbnails = new ThumbnailsPage();


function ThumbnailsTreeView(thumbnails, filter) // extend FilteredTreeView
{
    FilteredTreeView.call(this, thumbnails, filter);
}

ThumbnailsTreeView.prototype =
{
    getCellText: function(row, col)
    {
        var thumbnail = this.model[row];
        return thumbnail.thumbnailUrl;
    },
    
    getCellProperties: function(row, col)
    {
        let thumbnail = this.model[row];
        return "thumbnail_" + thumbnail.type;
    },
    
    getTooltipText: function(row, col)
    {
        let thumbnail = this.model[row];
        return _("thumbnailTypeTooltip", _("thumbnailType." + thumbnail.type));
    }
}

extend(ThumbnailsTreeView, FilteredTreeView);
